/*
 * Created by SharpDevelop.
 * User: Michael
 * Date: 13/09/2007
 * Time: 10:04 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;

namespace SudokuSolver
{
	/// <summary>
	/// Description of Cell.
	/// </summary>
	public class Cell
	{
		private bool[] _Possible = new bool[9];
		private bool _Found;
		private int _Value;
		private Group _Row, _Column, _Block;
		private int _RowNumber, _ColumnNumber, _BlockNumber;
		
		public Group Block {
			get { return _Block; }
		}
		
		public Group Column {
			get { return _Column; }
		}
		
		public Group Row {
			get { return _Row; }
		}
		
		public int BlockNumber {
			get { return _BlockNumber; }
		}
		
		public int ColumnNumber {
			get { return _ColumnNumber; }
		}
		
		public int RowNumber {
			get { return _RowNumber; }
		}
		
		public bool Found
		{
			get { return _Found; }
		}
		
		public string CandidateList
		{
			get {
				string result = "";
				for(int i = 1; i <= 9; i++)
				{
					if(this.IsPossible(i))
						result += i.ToString();
				}
				return result;
			}
		}
		
		public bool IsPossible(int index)
		{
			return _Possible[index - 1];
		}
		public void IsPossible(int index, bool isPossible)
		{
			_Possible[index - 1] = isPossible;
			if(this.CountPossible() == 0)
			{
				throw new InvalidSudokuException("One of the cells was set to have no possible values!", this);
			}
		}
		
		public int Value
		{
			get 
			{ 
				if(_Found)
				{
					return _Value;
				} else {
					return -1;
				}
				
			}
			set	
			{
				if ((!_Found) && ((value > 0) && (value < 10)))
				{
					_Found = true;
					_Value = value;
					for(int i = 1; i <= 9; i++)
					{
						if(i != value)
						{
							this.IsPossible(i, false);
						}
					}
				}
			}
		}
		
		public int CountPossible()
		{
			int count = 0;
			foreach(bool b in _Possible)
			{
				if(b)
					count++;
			}
			return count;
		}
		
		public Cell(Group row, int rownumber, Group column, int colnumber, Group block, int blocknumber)
		{
			//assign a row, column and block
			_Row = row;
			_Column = column;
			_Block = block;
			
			_RowNumber = rownumber + 1;
			_ColumnNumber = colnumber + 1;
			_BlockNumber = blocknumber;
			//set all possibilities to true
			for(int i = 0; i < _Possible.Length; i++)
				_Possible[i] = true;
		}
		
		public string ValueToString
		{
			get {
				if(Found)
					return Value.ToString();
				else
					return " ";
			}
		}
		
		public override string ToString()
		{
			char columnLetter = (char)(64 + ColumnNumber);
			return "Cell " + columnLetter.ToString() + RowNumber.ToString();
		}
	}
}
